package com.asha.md360player4android;

import android.Manifest;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.asha.md360player4android.vr.VrManager;
import com.asha.vrlib.MDVRLibrary;
import com.asha.vrlib.texture.MD360BitmapTexture;
import com.leon.lfilepickerlibrary.LFilePicker;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target;
import com.tbruyelle.rxpermissions2.RxPermissions;

import java.io.File;
import java.util.List;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;

import static com.squareup.picasso.MemoryPolicy.NO_CACHE;
import static com.squareup.picasso.MemoryPolicy.NO_STORE;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private static final int REQUEST_CODE_CHOOSE = 0;

    VrManager vrManager;
    private Target mTarget;

    private Uri mUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // no title
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        // full screen
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_main);
        vrManager = new VrManager("Fuyao");
        View view = findViewById(R.id.gl_view);
        vrManager.createVRLibrary(this, view, bitmapProvider, gestureListener);

        vrManager.onDisplayModeChange(VrManager.MODULE_INDEX_PANORAMA, this);

        findViewById(R.id.choose_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                RxPermissions rxPermissions = new RxPermissions(MainActivity.this);
                rxPermissions.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        .subscribe(new Observer<Boolean>() {
                            @Override
                            public void onSubscribe(Disposable d) {

                            }

                            @Override
                            public void onNext(Boolean aBoolean) {
                                if (aBoolean) {
                                    new LFilePicker()
                                            .withActivity(MainActivity.this)
                                            .withRequestCode(REQUEST_CODE_CHOOSE)
                                            .start();
                                } else {
                                    Toast.makeText(MainActivity.this, "Permission Denied!", Toast.LENGTH_LONG)
                                            .show();
                                }
                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });
            }
        });
        initCalibrate();
    }




    private MDVRLibrary.IBitmapProvider bitmapProvider = new MDVRLibrary.IBitmapProvider() {
        @Override
        public void onProvideBitmap(MD360BitmapTexture.Callback callback) {
            loadImage(mUri, callback);
        }
    };

    private MDVRLibrary.IGestureListener gestureListener = new MDVRLibrary.IGestureListener() {
        public void onClick(MotionEvent e) {
        }
    };

    private void loadImage(Uri uri, final MD360BitmapTexture.Callback callback) {
        if (uri == null){
            uri = getDrawableUri(R.drawable.car1);
        }
        mTarget = new Target() {
            @Override
            public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                // notify if size changed
                vrManager.onTextureResize(bitmap.getWidth(), bitmap.getHeight());
                // texture
                callback.texture(bitmap);
            }

            @Override
            public void onBitmapFailed(Drawable errorDrawable) {

            }

            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {

            }
        };
        Picasso.with(getApplicationContext()).load(uri).memoryPolicy(NO_CACHE, NO_STORE).into(mTarget);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_CHOOSE && resultCode == RESULT_OK) {
            List<String> list = data.getStringArrayListExtra("paths");
            mUri = Uri.fromFile(new File(list.get(0)));
            vrManager.notifyPlayerChanged();
        }
    }

    private Uri getDrawableUri(@DrawableRes int resId){
        Resources resources = getResources();
        return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + resources.getResourcePackageName(resId) + '/' + resources.getResourceTypeName(resId) + '/' + resources.getResourceEntryName(resId) );
    }


    private View calibrateLayout;
    private TextView radiusTextView;
    private TextView offsetXTextView;
    private TextView offsetYTextView;
    private SeekBar seekbar;
    private SeekBar seekbar3;
    private SeekBar seekbar4;


    //need called after initManager
    private void initCalibrate() {
        calibrateLayout = findViewById(R.id.calibrate_layout);
        radiusTextView = (TextView) findViewById(R.id.text_r);
        offsetXTextView = (TextView) findViewById(R.id.text_offset_x);
        offsetYTextView = (TextView) findViewById(R.id.text_offset_y);
        seekbar = (SeekBar) findViewById(R.id.seekBar);
        seekbar.setOnSeekBarChangeListener(onSeekBarChangeListener);
        seekbar3 = (SeekBar) findViewById(R.id.seekBar3);
        seekbar3.setOnSeekBarChangeListener(onSeekBarChangeListener);
        seekbar4 = (SeekBar) findViewById(R.id.seekBar4);
        seekbar4.setOnSeekBarChangeListener(onSeekBarChangeListener);

        findViewById(R.id.calibrate_ok_button).setOnClickListener(this);
        findViewById(R.id.calibrate_cancel_button).setOnClickListener(this);

        findViewById(R.id.inc_button).setOnClickListener(this);
        findViewById(R.id.dec_button).setOnClickListener(this);
        findViewById(R.id.inc_button3).setOnClickListener(this);
        findViewById(R.id.dec_button3).setOnClickListener(this);
        findViewById(R.id.inc_button4).setOnClickListener(this);
        findViewById(R.id.dec_button4).setOnClickListener(this);
        updateCalibrateUI();
    }

    private void updateCalibrateUI() {
        radiusTextView.setText("radius:" + vrManager.getRadius());
        offsetXTextView.setText("offset X:" + vrManager.getOffsetX());
        offsetYTextView.setText("offset Y:" + vrManager.getOffsetY());
        seekbar.setProgress(vrManager.getRadiusProgress());
        seekbar3.setProgress(vrManager.getOffsetXProgress());
        seekbar4.setProgress(vrManager.getOffsetYProgress());
    }

    private void showOrHideCalibrate(final boolean show) {
        if (null != calibrateLayout) {
            calibrateLayout.setVisibility(show ? View.VISIBLE : View.GONE);
        }
    }

    private SeekBar.OnSeekBarChangeListener onSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            switch (seekBar.getId()) {
                case R.id.seekBar:
                    vrManager.setRadiusProgress(seekBar.getProgress());
                    break;
                case R.id.seekBar3:
                    vrManager.setOffsetXProgress(seekBar.getProgress());
                    break;
                case R.id.seekBar4:
                    vrManager.setOffsetYProgress(seekBar.getProgress());
                    break;
            }
            vrManager.notifyCalibrateChange(getApplicationContext());
            updateCalibrateUI();
        }
    };

    private void updateProgress(SeekBar seekbar, boolean add) {
        int max = seekbar.getMax();
        int progress = seekbar.getProgress();
        if (add) {
            if (progress < max) {
                progress++;
            }
        } else {
            if (progress > 0) {
                progress--;
            }
        }
        seekbar.setProgress(progress);
        onSeekBarChangeListener.onStopTrackingTouch(seekbar);
    }




    @Override
    public void onClick(View v) {
        switch (v.getId()) {

            case R.id.calibrate_ok_button:
                //boolean calibrate = SharePreferenceManager.getCalibrateStatus(getContext());
                //if (calibrate) {
//                SharePreferenceManager.setCalibrateStatus(getApplicationContext(), false);
                showOrHideCalibrate(false);
                vrManager.saveCalibrate(getApplicationContext());
                vrManager.onDisplayModeChange(VrManager.MODULE_INDEX_FISH_EYE, getApplicationContext());
                //}
                break;

            case R.id.calibrate_cancel_button:
                break;

            case R.id.inc_button:
                updateProgress(seekbar, true);
                break;
            case R.id.dec_button:
                updateProgress(seekbar, false);
                break;
            case R.id.inc_button3:
                updateProgress(seekbar3, true);
                break;
            case R.id.dec_button3:
                updateProgress(seekbar3, false);
                break;
            case R.id.inc_button4:
                updateProgress(seekbar4, true);
                break;
            case R.id.dec_button4:
                updateProgress(seekbar4, false);

        }
    }

}
